package com.kg.elysia.service;

import com.kg.elysia.db.Mural;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpResponse;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.codec.BodyCodec;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 *
 * </p>
 *
 * @author zj
 * @since 2025/10/21 20:03
 */
@Slf4j
public class AiService {

    private final String OLLAMA_URL = "127.0.0.1";
    private final int OLLAMA_PORT = 11434;
    private final String OLLAMA_API = "/api/generate";
    private final String MODEL_NAME = "qwen3:4b";

    private final Vertx vertx;
    private final MuralService muralService;
    private final WebClient ollamaClient;

    public AiService(Vertx vertx,MuralService muralService) {
        this.vertx = vertx;
        this.muralService = muralService;
        WebClientOptions options = new WebClientOptions()
                .setConnectTimeout(5000)
                .setIdleTimeout(30000)
                .setMaxPoolSize(10);
        this.ollamaClient = WebClient.create(vertx, options);
    }

    public Future<JsonObject> ask(String question) {
        return Future.future(promise -> {
            try {
                muralService.getAllMurals()
                        .onSuccess(murals -> {
                            String context = fillContent(murals);
                            String prompt = """
                你是一位考古壁画研究领域的权威专家，具备深厚的考古学与艺术史知识。
                请根据以下真实资料回答问题，要求回答准确、专业、条理清晰,并且要回答自然,不要刻意,但是必须围绕着提供的以下真实资料回答,并且是要以以下真实资料为主。
                --- 壁画资料 ---
                %s
                ----------------
                问题：%s
                """.formatted(context, question);
                            callOllama(prompt, promise);
                        })
                        .onFailure(promise::fail);
            } catch (Exception e) {
                e.printStackTrace();
                promise.fail(e.getMessage());
            }
        });
    }

    /**
     * 调用 Ollama /api/generate 接口
     */
    private void callOllama(String prompt, Promise<JsonObject> promise) {
        JsonObject requestJson = new JsonObject()
                .put("model", MODEL_NAME)
                .put("prompt", prompt)
                .put("stream", false);

        ollamaClient.post(OLLAMA_PORT, OLLAMA_URL, OLLAMA_API)
                .putHeader("Content-Type", "application/json")
                .as(BodyCodec.buffer())
                .sendJsonObject(requestJson, ar -> {
                    if (ar.succeeded()) {
                        try {
                            HttpResponse<Buffer> response = ar.result();
                            if (response.statusCode() != 200) {
                                String body = response.bodyAsString();
                                promise.fail("HTTP " + response.statusCode() + ", body: " + body);
                                return;
                            }
                            // 获取原始响应内容
                            String rawBody = response.bodyAsString();
                            // 手动解析 JSON
                            JsonObject jsonResponse = new JsonObject(rawBody);
                            String reply = jsonResponse.getString("response", "").trim();
                            log.info("AI 回复: {}", reply);

                            JsonObject result = new JsonObject()
                                    .put("answer", reply)
                                    .put("success", true);

                            promise.complete(result);
                        } catch (Exception e) {
                            // 打印原始响应，帮助定位问题
                            String body = ar.result().bodyAsString();
                            System.err.println("Invalid JSON received: " + body);
                            promise.fail("JSON 解析失败: " + e.getMessage() + " | 原始内容: " + body);
                        }
                    } else {
                        promise.fail("HTTP 请求失败: " + ar.cause().getMessage());
                    }
                });
    }

    private String fillContent(JsonArray murals) {
        StringBuilder sb = new StringBuilder();
        for (Object mural : murals) {
            Mural m = new Mural((JsonObject) mural);
            sb.append(m.toContent());
        }
        return sb.toString();
    }
}
